package com.yykj.hospital.server.service.impl;

import com.google.common.base.Joiner;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import com.yykj.common.util.LocalObjectUtil;
import com.yykj.common.util.LocalStringUtil;
import com.yykj.hospital.client.dto.HospitalAdminRoleDTO;
import com.yykj.hospital.client.dto.HospitalAdminRoleDetailDTO;
import com.yykj.hospital.client.dto.HospitalMenuDTO;
import com.yykj.hospital.client.dto.HospitalMenuListDTO;
import com.yykj.hospital.client.form.HospitalMenuForm;
import com.yykj.hospital.server.converter.HospitalAdminRoleDTOConverter;
import com.yykj.hospital.server.converter.HospitalMenuDTOConverter;
import com.yykj.hospital.server.model.entity.HospitalAdmin;
import com.yykj.hospital.server.model.entity.HospitalAdminRole;
import com.yykj.hospital.server.model.entity.HospitalDepartment;
import com.yykj.hospital.server.model.entity.HospitalMenu;
import com.yykj.hospital.server.model.repository.HospitalAdminRepository;
import com.yykj.hospital.server.model.repository.HospitalAdminRoleRepository;
import com.yykj.hospital.server.model.repository.HospitalMenuRepository;
import com.yykj.hospital.server.service.HospitalOauthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class HospitalOauthServiceImpl implements HospitalOauthService {

    @Override
    public List<HospitalMenuDTO> getHospitalMenu(Integer hospitalId, String keyword) {
        List<HospitalMenu> list;
        if (StringUtils.isEmpty(keyword)) {
            list = hospitalMenuRepository.findAllByHospitalId(hospitalId);
        } else {
            list = hospitalMenuRepository.findAllByHospitalIdAndMenuNameLikeOrMenuCodeLike(hospitalId, LocalStringUtil.getLikeString(keyword), LocalStringUtil.getLikeString(keyword));
        }

        return HospitalMenuDTOConverter.convert(list);
    }

    @Override
    public HospitalMenuDTO editHospitalMenu(HospitalMenuForm hospitalMenuForm) {
        if (hospitalMenuForm.getPid() == null || hospitalMenuForm.getPid() < 0) {
            hospitalMenuForm.setPid(0);
        }
        HospitalMenu hospitalMenu = null;
        if (hospitalMenuForm.getId() != null && hospitalMenuForm.getId() > 0) {//修改
            hospitalMenu = findById(hospitalMenuForm.getId());
            LocalObjectUtil.copyNullValue(hospitalMenuForm, hospitalMenu);
        } else {//新增
            hospitalMenu = new HospitalMenu();
            BeanUtils.copyProperties(hospitalMenuForm, hospitalMenu);
        }
        hospitalMenu = hospitalMenuRepository.save(hospitalMenu);

        return HospitalMenuDTOConverter.convert(hospitalMenu);
    }

    @Override
    public void deleteHospitalMenu(Integer id) {
        HospitalMenu hospitalMenu = findById(id);
        hospitalMenuRepository.delete(hospitalMenu);
    }

    @Override
    public List<HospitalMenuListDTO> getHospitalAdminMenu(Integer adminId) {
        HospitalAdmin admin = hospitalAdminRepository.findById(adminId).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
        List<HospitalMenu> hospitalMenuList;
        if (admin.getUsername().equals("admin")) {
            hospitalMenuList = hospitalMenuRepository.findAll();
        } else {
            String[] split = admin.getRoleIds().split(",");
            List<Integer> roleIds = new ArrayList<>();
            for (String s : split) {
                roleIds.add(Integer.parseInt(s));
            }
            List<HospitalAdminRole> roleList = hospitalAdminRoleRepository.findAllByIdIn(roleIds);
            List<Integer> oauthIds = new ArrayList<>();
            for (HospitalAdminRole role : roleList) {
                String[] split1 = role.getOauthIds().split(",");
                for (String s : split1) {
                    oauthIds.add(Integer.parseInt(s));
                }
            }
            hospitalMenuList = hospitalMenuRepository.findAllByIdIn(oauthIds);

        }

        return formatHospitalMenu(hospitalMenuList);
    }

    private List<HospitalMenuListDTO> formatHospitalMenu(List<HospitalMenu> hospitalMenuList) {
        List<HospitalMenuListDTO> result = new ArrayList<>();
        for (HospitalMenu oauth : hospitalMenuList) {
            if (oauth.getPid() == 0) {
                HospitalMenuListDTO listDTO = new HospitalMenuListDTO();
                BeanUtils.copyProperties(oauth, listDTO);
                for (HospitalMenu child : hospitalMenuList) {
                    if (oauth.getId().equals(child.getPid())) {
                        HospitalMenuDTO subMenu = new HospitalMenuDTO();
                        BeanUtils.copyProperties(child, subMenu);
                        listDTO.getChild().add(subMenu);
                    }
                }
                result.add(listDTO);
            }
        }
        return result;
    }


    @Override
    public HospitalAdminRoleDTO editRole(HospitalAdminRoleDTO form) {
        HospitalAdminRole role;
        if (form.getId() != null && form.getId() > 0) {
            role = hospitalAdminRoleRepository.findById(form.getId()).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
        } else {
            role = new HospitalAdminRole();
        }
        BeanUtils.copyProperties(form, role);
        if (form.getOauthIds() == null || form.getOauthIds().size() == 0) {
            role.setOauthIds("");
        } else {
            role.setOauthIds(Joiner.on(",").join(form.getOauthIds()));
        }
        hospitalAdminRoleRepository.save(role);
        return HospitalAdminRoleDTOConverter.convert(role);
    }

    @Override
    public void deleteRole(Integer id) {
        HospitalAdminRole role = hospitalAdminRoleRepository.findById(id).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
        hospitalAdminRoleRepository.delete(role);
    }

    @Override
    public List<HospitalAdminRoleDetailDTO> getHospitalAdminRole(Integer hospitalId, Integer adminId) {
        List<HospitalAdminRole> adminRoleList;
        if (adminId != null && adminId > 0) {
            HospitalAdmin admin = hospitalAdminRepository.findById(adminId).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
            if (admin.getUsername().equals("admin")) {
                adminRoleList = hospitalAdminRoleRepository.findAll();
            } else {
                String[] split = admin.getRoleIds().split(",");
                List<Integer> roleIds = new ArrayList<>();
                for (String s : split) {
                    roleIds.add(Integer.parseInt(s));
                }
                adminRoleList = hospitalAdminRoleRepository.findAllByIdIn(roleIds);

            }
        } else {
            adminRoleList = hospitalAdminRoleRepository.findAll();
        }

        List<HospitalAdminRoleDetailDTO> result = new ArrayList<>();

        for (HospitalAdminRole adminRole : adminRoleList) {
            HospitalAdminRoleDetailDTO dto = new HospitalAdminRoleDetailDTO();
            BeanUtils.copyProperties(adminRole, dto);
            List<HospitalMenu> menuList = new ArrayList<>();
            if (!StringUtils.isEmpty(adminRole.getOauthIds())) {
                String[] split = adminRole.getOauthIds().split(",");
                List<Integer> oauthIds = new ArrayList<>();
                for (String s : split) {
                    oauthIds.add(Integer.parseInt(s));
                }
                menuList = hospitalMenuRepository.findAllByIdIn(oauthIds);
            }

            dto.setOauth(formatHospitalMenu(menuList));
            result.add(dto);
        }
        return result;
    }

    @Override
    public void initHospitalMenu(Integer hospitalId) {
        List<HospitalMenu> hospitalMenuList = hospitalMenuRepository.findAllByHospitalId(10001);
        List<HospitalMenu> list = new ArrayList<>();
        for (HospitalMenu parentMenu : hospitalMenuList) {
            if (parentMenu.getPid() == 0) {
                HospitalMenu parent = new HospitalMenu();
                BeanUtils.copyProperties(parentMenu, parent);
                parent.setHospitalId(hospitalId);
                parent.setId(null);
                parent = hospitalMenuRepository.save(parent);
                list.clear();
                for (HospitalMenu childMenu : hospitalMenuList) {
                    if(childMenu.getPid().equals(parentMenu.getId())){
                        HospitalMenu child = new HospitalMenu();
                        BeanUtils.copyProperties(childMenu, child);
                        child.setPid(parent.getId());
                        child.setHospitalId(hospitalId);
                        child.setId(null);
                        list.add(child);
                    }
                }
                hospitalMenuRepository.saveAll(list);
            }
        }
    }

    private HospitalMenu findById(Integer id) {
        return hospitalMenuRepository.findById(id).orElseThrow(() -> new NormalException(ResultEnums.NOT_EXIST));
    }

    private HospitalMenuRepository hospitalMenuRepository;

    private HospitalAdminRepository hospitalAdminRepository;

    private HospitalAdminRoleRepository hospitalAdminRoleRepository;

    @Autowired
    public void setHospitalMenuRepository(HospitalMenuRepository hospitalMenuRepository) {
        this.hospitalMenuRepository = hospitalMenuRepository;
    }

    @Autowired
    public void setHospitalAdminRepository(HospitalAdminRepository hospitalAdminRepository) {
        this.hospitalAdminRepository = hospitalAdminRepository;
    }

    @Autowired
    public void setHospitalAdminRoleRepository(HospitalAdminRoleRepository hospitalAdminRoleRepository) {
        this.hospitalAdminRoleRepository = hospitalAdminRoleRepository;
    }
}
